"""
Example Echo channel, useful for testing.

Copyright (c) 2009 Christopher Hesse
http://code.google.com/p/python-expect/
"""

import Queue
import logging
from expect.selectable import Selectable
from expect.exceptions import ChannelClosed
from .base import BaseChannel

log = logging.getLogger(__name__)


class EchoChannel(BaseChannel):
    """
    An example channel, any data written to the channel with .write() can be
    read from it later with .read().
    """
    
    def __init__(self, **kwargs):
        super(EchoChannel, self).__init__(**kwargs)
        self.selectable = Selectable()
        self.queue = Queue.Queue()
        self._closed = False
    
    def flush(self):
        # There's no data to flush
        pass
        
    def fileno(self):
        return self.selectable.fileno()
        
    def write(self, data):
        if self.closed:
            raise ChannelClosed("tried to write to a closed channel")
            
        with self.selectable:
            self.queue.put(data)
            self.selectable.set()
            
        self._log_write(data)
        
    def read(self, size=-1):
        if self.closed:
            return ''
        
        buffers = []
        with self.selectable:
            for i in xrange(self.queue.qsize()):
                buffers.append(self.queue.get_nowait())
            self.selectable.clear()
        data = ''.join(buffers)
        self._log_read(data)
        return data
        
    def close(self):
        self.queue = None
        self.selectable.set()
        self._closed = True
        log.debug("closed channel", **self._log_info())
    
    @property
    def closed(self):
        return self._closed